package com.quectel.taskserver.job.propertybill;

import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.propertybill.PropertyBillBusiness;
import com.quectel.constant.PushConstants;
import com.quectel.constant.core.propertybill.PropertyBillConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.propertybill.dto.PropertyBillDto;
import com.quectel.core.module.propertybill.dto.PropertyChargeableListDto;
import com.quectel.core.module.propertybill.dto.PropertyChargeableListDueDateDto;
import com.quectel.core.module.propertybill.service.PropertyBillService;
import com.quectel.core.module.propertybill.service.PropertyChargeableListDueDateService;
import com.quectel.core.module.propertybill.service.PropertyChargeableListService;
import com.quectel.core.module.propertybill.vo.PropertyBillAmountVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2023/4/14 16:05
 * @description new java file header...
 */
@Component
@Slf4j
public class PropertyBillJob implements DataflowJob<PropertyChargeableListDueDateDto> {
    @DubboReference
    private PropertyBillService propertyBillService;
    @DubboReference
    private PropertyChargeableListService propertyChargeableListService;
    @DubboReference
    private PropertyChargeableListDueDateService propertyChargeableListDueDateService;

    @Autowired
    private PropertyBillBusiness propertyBillBusiness;

    @Override
    public List<PropertyChargeableListDueDateDto> fetchData(ShardingContext shardingContext) {
        log.info("开始收费标准过期时间信息，当前在分片:{}", shardingContext.getShardingItem());
        //查询所有的收费标准
        Map<String, Object> params = new HashMap<>();
        params.put(LambdaUtil.getFieldName(PropertyChargeableListDto::getStatus), SystemConstants.NORMAL);
        List<PropertyChargeableListDto> propertyChargeableListDtos = propertyChargeableListService.queryList(params);
        List<PropertyChargeableListDueDateDto> list = new ArrayList<>();
        //根据收费标准查询所有的过期收费记录
        for (PropertyChargeableListDto propertyChargeableListDto : propertyChargeableListDtos) {
            // 查询对应的逾期时间
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put(LambdaUtil.getFieldName(PropertyChargeableListDueDateDto::getTenantId), propertyChargeableListDto.getTenantId());
            queryParams.put(LambdaUtil.getFieldName(PropertyChargeableListDueDateDto::getVillageId), propertyChargeableListDto.getVillageId());
            queryParams.put(LambdaUtil.getFieldName(PropertyChargeableListDueDateDto::getChargeableListId), propertyChargeableListDto.getId());
            //提前账单生成时间
            Date date = DateUtils.addDays(new Date(), -propertyChargeableListDto.getOverdueDays());
            queryParams.put(LambdaUtil.getFieldName(PropertyChargeableListDueDateDto::getDueDate), com.quectel.util.common.DateUtils.format(date, com.quectel.util.common.DateUtils.FormatType.SIMPLE));
            queryParams.put(SystemConstants.SHARDING_SLOT_KEY_PAIR.getLeft(), shardingContext.getShardingTotalCount());
            queryParams.put(SystemConstants.SHARDING_SLOT_KEY_PAIR.getRight(), shardingContext.getShardingItem());
            List<PropertyChargeableListDueDateDto> propertyChargeableListDueDateDtos = propertyChargeableListDueDateService.queryList(queryParams);
            list.addAll(propertyChargeableListDueDateDtos);
        }
        log.info("开始收费标准过期时间信息，抽取到数据总量:{},当前在分片:{}", list.size(), shardingContext.getShardingItem());
        return list;
    }


    @Override
    public void processData(ShardingContext shardingContext, List<PropertyChargeableListDueDateDto> list) {
        log.info("生成账单开始，当前在分片:{}", shardingContext.getShardingItem());

        for (PropertyChargeableListDueDateDto dueDateDto : list) {
            try {
                //新的开始时间
                Date startDate = DateUtils.addDays(dueDateDto.getDueDate(), 1);
                PropertyBillAmountVo propertyBillAmountVo = propertyBillBusiness.generatePropertyBill(dueDateDto.getChargeableListId(), dueDateDto.getRoomId(), startDate, Boolean.FALSE);
                //查询是否存在账单,存在则不保存
                Map<String, Object> params = new HashMap<>();
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getTenantId), dueDateDto.getTenantId());
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getVillageId), dueDateDto.getVillageId());
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getRoomId), dueDateDto.getRoomId());
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getYear), propertyBillAmountVo.getBillCycleDateInfoVo().getYear());
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getPeriodType), propertyBillAmountVo.getBillCycleDateInfoVo().getPeriodType());
                params.put(LambdaUtil.getFieldName(PropertyBillDto::getPeriodValue), propertyBillAmountVo.getBillCycleDateInfoVo().getPeriodValue());
                int i = propertyBillService.queryTotal(params);
                if (i <= 0) {
                    PropertyBillDto propertyBillDto = propertyBillBusiness.genBillByPropertyBillAmountVo(propertyBillAmountVo);
                    //保存订单信息,不带支付详情
                    propertyBillDto.setId(propertyBillService.save(propertyBillDto));

                    //账单生成通知
                    propertyBillBusiness.sendPropertyBillMsg(propertyBillDto.getId(), Arrays.asList(PushConstants.PushType.WECHAT_OFFICIAL.getType()), PropertyBillConstants.MsgType.ADD.getType());
                }
            } catch (IllegalArgumentException e) {
                log.error("PropertyBillJob processData error");
            }
        }

        log.info("生成账单结束，当前在分片:{}", shardingContext.getShardingItem());
    }
}
